<template>
  <div>
    <div>平行光阴影计算二</div>
    <div ref="webgl"></div>
  </div>
</template>
<script lang="ts" setup>
  import * as THREE from 'three';
  import { OrbitControls } from 'three/addons';
  import { onMounted, ref } from 'vue';

  const webgl: any = ref(null);
  let scene: any = null;
  let camera: any = null;
  let render: any = null;
  let controls: OrbitControls;
  onMounted(() => {
    init();
  });
  function init() {
    scene = new THREE.Scene();

    const width = window.innerWidth; //canvas画布宽度
    const height = window.innerHeight; //canvas画布高度

    camera = new THREE.PerspectiveCamera(45, width / height, 1, 100);
    camera.position.set(300, 300, 300);
    camera.lookAt(scene.position);
    render = new THREE.WebGLRenderer();
    // 背景颜色
    render.setClearColor('#f1f2f6');
    render.setSize(width, height);
    // 设置渲染器，允许光源阴影渲染
    render.shadowMap.enabled = true;
    // render.shadowMap.type = THREE.PCFSoftShadowMap;

    webgl.value.appendChild(render.domElement);
    controls = new OrbitControls(camera, render.domElement);
    // const amLight = new THREE.AmbientLight(0xffffff);
    // scene.add(amLight);
    const helper = new THREE.AxesHelper(200);
    scene.add(helper);
    // 平行光
    const dirLight = new THREE.DirectionalLight(0xffffff, 3);
    dirLight.position.set(-3, 10, -10);
    dirLight.castShadow = true;
    dirLight.shadow.camera.top = 2;
    dirLight.shadow.camera.bottom = -2;
    dirLight.shadow.camera.left = -2;
    dirLight.shadow.camera.right = 2;
    dirLight.shadow.camera.near = 0.1;
    dirLight.shadow.camera.far = 40;
    scene.add(dirLight);
    // 可视化平行光阴影对应的正投影相机对象
    const cameraHelper = new THREE.CameraHelper(dirLight.shadow.camera);
    scene.add(cameraHelper);
    // 地面
    const mesh = new THREE.Mesh(
      new THREE.PlaneGeometry(100, 100),
      new THREE.MeshPhongMaterial({ color: 0xcbcbcb, depthWrite: false }),
    );
    mesh.rotation.x = -Math.PI / 2;
    mesh.receiveShadow = true;
    scene.add(mesh);

    // 物体

    const materialMesh = new THREE.Mesh(
      new THREE.BoxGeometry(1, 1, 3),
      new THREE.MeshBasicMaterial({
        color: '#d29200',
      }),
    );
    materialMesh.castShadow = true;
    scene.add(materialMesh);

    renderFun();
  }

  function renderFun() {
    controls.update();
    // controls.update(); //update()函数内会执行camera.lookAt(controls.target)
    render.render(scene, camera);
    requestAnimationFrame(renderFun);
  }
</script>
<style lang=""></style>
